package com.meng.listview_scrolldelete;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.AbsListView;
import android.widget.ListView;
import android.widget.Toast;

import java.lang.reflect.Field;

/**
 * Created by Administrator on 2017/5/19.
 */

public class MyListView extends ListView{
    private int mTouchSlop;
    private VelocityTracker mVelocityTracker;
    private int mMaximumVelocity;
    private int mMinimumVelocity;
    public MyListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }
    public MyListView(Context context) {
        super(context);
        init();
    }
    @Override
    public void setOnScrollListener(OnScrollListener l) {
        this.onScrollListener = l;
    }
    private OnScrollListener onScrollListener;
    private boolean isScrollStateTouchScroll;
    private void init() {
        final ViewConfiguration configuration = ViewConfiguration.get(getContext());
        mTouchSlop = configuration.getScaledTouchSlop();
        mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
        mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
        super.setOnScrollListener(new OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                if(onScrollListener != null){
                    onScrollListener.onScrollStateChanged(view,scrollState);
                }
                switch (scrollState){
                    case SCROLL_STATE_TOUCH_SCROLL:
                        isScrollStateTouchScroll = true;
                        break;
                    case SCROLL_STATE_IDLE:
                        isScrollStateTouchScroll = false;
                        break;
                }
            }
            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                if(onScrollListener != null){
                    onScrollListener.onScroll(view,firstVisibleItem,visibleItemCount,totalItemCount);
                }
            }
        });
    }
    private float mDownX,mDownY;
    private ItemLayout mCurItemLayout;
    private float mLastX;

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        Log.d("MyListView", "ev.getAction():" + ev.getAction());
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                mLastX = mDownX = ev.getX(); //记录刚触摸时的x坐标
                mDownY = ev.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                if(Math.abs(ev.getX() - mDownX) > mTouchSlop){
                    if(isShowMenu()){


                    }
                    return true;
                }
                break;
        }

        return super.onInterceptTouchEvent(ev) ;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        Log.d("MyListView", "onTouchEvent:"+ev.getAction());
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                return touchDown(ev);
            case MotionEvent.ACTION_MOVE:
                return touchMove(ev);
            case MotionEvent.ACTION_UP:
                return touchUp(ev);

        }
        return super.onTouchEvent(ev);
    }

    private boolean touchUp(MotionEvent ev) {
        Log.d("MyListView", "up" + mCurItemLayout);
        if(mCurItemLayout != null){
            if(mCurItemLayout.isMenuOpened()){
                closeItemMenu();
                return true;
            }
            if(mCurItemLayout.isShowMenu()){//如果menu还是显示的
                mVelocityTracker.computeCurrentVelocity(1000);
                if(mVelocityTracker.getXVelocity() > mMinimumVelocity){//向右快速滚动
                    closeItemMenu();
                    return true;
                }else if(mVelocityTracker.getXVelocity() < -mMinimumVelocity){
                    showItemMenu();
                    Log.d("MyListView", "mVelocityTracker.getXVelocity():" + mVelocityTracker.getXVelocity());
                    Log.d("MyListView", "showItemMenu");
                    return true;
                }
                Toast.makeText(getContext(), "up isScrollStateTouchScroll:" + isScrollStateTouchScroll, Toast.LENGTH_SHORT).show();
                if(!isScrollStateTouchScroll){
                    closeItemMenu();
                    return true;
                }
                if(mCurItemLayout.shouleOpenMenu()){
                    showItemMenu();
                }else{
                    closeItemMenu();
                }
            }
            return true;
        }
        return super.onTouchEvent(ev);
    }

    private boolean touchMove(MotionEvent ev) {
        if(isScrollStateTouchScroll ){
            return super.onTouchEvent(ev);
        }
        if(!isShowMenu() && mDownX - ev.getX() > mTouchSlop && Math.abs(ev.getY()-mDownY) < mDownX - ev.getX()){
            mCurItemLayout = getItemLayout(getPositionForList(ev.getX(),ev.getY()));
            clearDrawableState();
        }
        if(isShowMenu()){
            mVelocityTracker.addMovement(ev);
            int scrollX = (int) (mLastX - ev.getX());
            if(mCurItemLayout.getScrollX() + scrollX <=0){
                scrollX = -mCurItemLayout.getScrollX();
            }
            if(mCurItemLayout.getScrollX() + scrollX >= mCurItemLayout.getMenuWidth()){
                scrollX = mCurItemLayout.getMenuWidth() - mCurItemLayout.getScrollX();
            }
            mCurItemLayout.scrollBy(scrollX,0);
            mLastX = ev.getX();
            return true;
        }
        Log.d("MyListView", "touchMove " + isShowMenu());
        return super.onTouchEvent(ev);
    }

    private boolean touchDown(MotionEvent ev) {
        initOrResetVelocityTracker();
        mVelocityTracker.addMovement(ev);
        mLastX = mDownX = ev.getX(); //记录刚触摸时的x坐标
        mDownY = ev.getY();
        if(mCurItemLayout != null && !mCurItemLayout.isShowMenu() ){
            mCurItemLayout = null;
        }
        if(mCurItemLayout != null && mCurItemLayout.isShowMenu()){//如果itemMenu已经显示，触摸非这个item的时候就关闭itemMenu
            if(mCurItemLayout != getItemLayout(getPositionForList(ev.getX(),ev.getY()))){
                mCurItemLayout.closeMenu();
                mCurItemLayout = null;
                return false;
            }
        }
        return super.onTouchEvent(ev);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        releaseVelocityTracker();
    }
    public void releaseVelocityTracker(){
        if(mVelocityTracker!=null){
            mVelocityTracker.clear();
            mVelocityTracker.recycle();
            mVelocityTracker=null;
        }
    }
    private void showItemMenu() {
        mCurItemLayout.showMenu();
        clearDrawableState();
    }

    private void closeItemMenu(){
        mCurItemLayout.closeMenu();
        clearDrawableState();
        mCurItemLayout = null;
    }
    private void initVelocityTrackerIfNotExists() {
        if (mVelocityTracker == null) {
            mVelocityTracker = VelocityTracker.obtain();
        }
    }
    private void initOrResetVelocityTracker() {
        if (mVelocityTracker == null) {
            mVelocityTracker = VelocityTracker.obtain();
        } else {
            mVelocityTracker.clear();
        }
    }
    private int getPositionForList(float x,float y){
        return pointToPosition((int)x,(int)y);
    }
    private ItemLayout getItemLayout(int positionForList){
        int pos = positionForList - getFirstVisiblePosition();
        View itemView = getChildAt(pos);
        return (ItemLayout) itemView;
    }
    /**
     * 是否是显示Menu状态
     * @return
     */
    private boolean isShowMenu(){
        return mCurItemLayout != null;
    }
    private Field mTouchModeField;
    private void clearDrawableState(){
        if(mTouchModeField == null){
            try {
                mTouchModeField = AbsListView.class.getDeclaredField("mTouchMode");
                mTouchModeField.setAccessible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        try {
            mTouchModeField.set(this,-1);//设置为TOUCH_MODE_REST
            drawableStateChanged();
        } catch (Exception e) {
        }
    }


}
